using System;

namespace Pomelo.DotNetClient
{
	/// <summary>
	/// package分为header和body两部分。header描述package包的类型和包的长度，body则是需要传输的数据内容。具体格式如下：
	/// type - package类型，1个byte，取值如下。
	/// 0x01: 客户端到服务器的握手请求以及服务器到客户端的握手响应
	/// 0x02: 客户端到服务器的握手ack
	/// 0x03: 心跳包
	/// 0x04: 数据包
	/// 0x05: 服务器主动断开连接通知
	/// length - body内容长度，3个byte的大端整数，因此最大的包长度为2^24个byte。
	/// body - 二进制的传输内容。
	/// 各个package类型的具体描述和控制流程如下。
	/// </summary>
    public class PackageProtocol
    {
        public const int HEADER_LENGTH = 4;

        public static byte[] encode(PackageType type)
        {
            return new byte[] { Convert.ToByte(type), 0, 0, 0 };
        }

        public static byte[] encode(PackageType type, byte[] body)
        {
            int length = HEADER_LENGTH;

            if (body != null) length += body.Length;

            byte[] buf = new byte[length];

            int index = 0;

            buf[index++] = Convert.ToByte(type);
			// >>右位移
            buf[index++] = Convert.ToByte(body.Length >> 16 & 0xFF);
            buf[index++] = Convert.ToByte(body.Length >> 8 & 0xFF);
            buf[index++] = Convert.ToByte(body.Length & 0xFF);

            while (index < length)
            {
                buf[index] = body[index - HEADER_LENGTH];
                index++;
            }

            return buf;
        }

        public static Package decode(byte[] buf)
        {
            PackageType type = (PackageType)buf[0];

            byte[] body = new byte[buf.Length - HEADER_LENGTH];

            for (int i = 0; i < body.Length; i++)
            {
                body[i] = buf[i + HEADER_LENGTH];
            }

            return new Package(type, body);
        }
    }
}